package com.pactera.asmp.server.service;

import com.alibaba.fastjson.JSONObject;
import com.pactera.asmp.server.common.constants.Constants;
import com.pactera.asmp.server.common.constants.DeviceEnum;
import com.pactera.asmp.server.common.constants.Result;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.domain.Audience;
import com.pactera.asmp.server.common.utils.JwtTokenUtil;
import io.jsonwebtoken.ExpiredJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @ProjectName: tlsserver
 * @Package com.pactera.asmp.server.service
 * @ClassName: TokenServiceImpl
 * @Description: Token业务 实现
 * @Date 2020/06/02 10:23
 * @Author lvzhiqiang
 * @Version 1.0
 */
@Service
public class TokenServiceImpl implements ITokenService {
    private static final Logger logger = LoggerFactory
            .getLogger(TokenServiceImpl.class);

    @Autowired
    private Audience audience;
    @Autowired
    private RedisServiceImpl mRedisService;

    @Override
    public String createToken(String userId, String roleId, int channelId) {
        String token = JwtTokenUtil.createJWT(userId, roleId, channelId, audience);
        logger.info("audience.getExpiresSecond():" + audience.expiresSecond);
        //response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, JwtTokenUtil.TOKEN_PREFIX + token);
        int timeout = new Random().nextInt(99) + audience.expiresSecond;
        logger.info("createToken token"+ token +"  timeout :"+timeout);
        mRedisService.setex(Constants.REDIS_TOKEN_KEY + channelId + ":" + userId, token, TimeUnit.SECONDS, timeout);
        JSONObject result = new JSONObject();
        result.put("token", token);
        return token;
    }

    @Override
    public Result refreshToken(String oldToken, int channelId) {
        //UUID :Unique Ingredient Identifier
        //JWT = UUID + channelId + createTime + IpAddress
        //备注：channelId  0：Android IVI APP 1：Android app 2. IOS APP  3. PC  4. TrafficLight  不同channelId对应的UII意义不同
        //1. OldToken 在redis中已失效，但是JWT没有超期，则需要解析OldToken获取UUID，根据UUID产生新的token
        //2. OldToken 在redis中已失效，且JWT也超期了，则此时返回错误码 用户重新登录/设备端重新调用registerAPI获取新的Token，并更新到Redis
        //3. OldToken 在redis中未失效，此时直接删除redis中该token对应的那条记录，并重新产生新的token返回给客户端
        String uuid = null;
        String roleId = null;
        try {
            uuid = JwtTokenUtil.getUUID(oldToken, audience.base64Secret);
            roleId = JwtTokenUtil.getRoleId(oldToken, audience.base64Secret);
        } catch (ExpiredJwtException eje) {
            switch (DeviceEnum.value(channelId)) {
                case IVI_DEVICE_APP:
                case TRAFFIC_LIGHT:
                    return Result.FAIL(ResultCode.PERMISSION_TOKEN_INVALID.message());
                case PC_BROWSER:
                case UNKNOW_DEVICE:
                    return Result.FAIL(ResultCode.PERMISSION_UNAUTHENTICATED.message());
                default:

            }
        } catch (Exception e) {
            return Result.FAIL(ResultCode.PERMISSION_TOKEN_INVALID.message());
        }

        JSONObject result = new JSONObject();
        String token = JwtTokenUtil.createJWT(uuid, roleId, channelId, audience);
        int timeout = new Random().nextInt(99) + audience.expiresSecond;
        logger.info("refreshToken token"+ token +"  timeout :"+timeout);
        mRedisService.setex(Constants.REDIS_TOKEN_KEY + channelId + ":" + uuid, token, TimeUnit.SECONDS, timeout);
        logger.info("audience.getExpiresSecond():" + audience.expiresSecond);
        result.put("token", token);
        if (mRedisService.hasKey(oldToken)) {
            mRedisService.setex(oldToken, uuid, TimeUnit.SECONDS,10);
        }
        return Result.SUCCESS(result);

    }
}
